package com.xuecheng.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xuecheng.dto.BindTeachplanMediaDto;
import com.xuecheng.dto.SaveTeachplanDto;
import com.xuecheng.dto.TeachplanDto;
import com.xuecheng.exception.XuechengOnlineException;
import com.xuecheng.mapper.TeachplanMapper;
import com.xuecheng.mapper.TeachplanMediaMapper;
import com.xuecheng.po.Teachplan;
import com.xuecheng.po.TeachplanMedia;
import com.xuecheng.service.TeachplanService;
import org.apache.ibatis.javassist.compiler.ast.Variable;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

@Service
public class TeachplanServiceImpl implements TeachplanService {
    @Autowired
    TeachplanMapper teachplanMapper;

    @Autowired
    TeachplanMediaMapper teachplanMediaMapper;
    /**
     * 查询某课程的课程计划，组成树形结构
     *
     * @param courseId
     * @return
     */
    @Override
    public List<TeachplanDto> findTeachplanTree(Long courseId) {
        return teachplanMapper.selectTreeNodes(courseId);
    }

    /**
     * 保存课程计划（根据是否有课程计划id，来判断是要修改课程计划，还是新增课程计划
     *
     * @param saveTeachplanDto
     */
    @Transactional
    @Override
    public void saveTeachplan(SaveTeachplanDto saveTeachplanDto) {

        //课程计划id
        Long id = saveTeachplanDto.getId();

        //修改课程计划
        if(id != null){
            Teachplan teachplan = teachplanMapper.selectById(id);
            BeanUtils.copyProperties(saveTeachplanDto,teachplan);
            teachplanMapper.updateById(teachplan);
        }else{
            //取出同父级别的课程计划数量
            int count = getTeachplanCount(saveTeachplanDto.getCourseId(), saveTeachplanDto.getParentid());
            Teachplan teachplanNew = new Teachplan();

            //设置排序号
            teachplanNew.setOrderby(count + 1);
            BeanUtils.copyProperties(saveTeachplanDto,teachplanNew);
            teachplanMapper.insert(teachplanNew);
        }
    }

    /**
     * 获取最新的排序号
     * @param courseId  课程id
     * @param parentid  父课程计划id
     * @return  最新排序号
     */
    private int getTeachplanCount(Long courseId, Long parentid) {
        LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Teachplan::getCourseId,courseId);
        queryWrapper.eq(Teachplan::getParentid,parentid);
        Integer count = teachplanMapper.selectCount(queryWrapper);
        return count;
    }


    /**
     * 根据课程计划id删除
     *
     * @param id
     */
    @Transactional
    @Override
    public void deleteTeachplan(Long id) {
        //删除大章节时，要求大章节下面没有小章节才可以删除
        //删除小章节时，同时把teachplan_media表的关联信息也删除

        Teachplan teachplan = teachplanMapper.selectById(id);
        if(teachplan == null){
            throw new XuechengOnlineException("课程计划不存在","12408");
        }
        Long parentid = teachplan.getParentid();
        if(parentid == 0){
            //parentid=0是大章节，首先判断是否存在子章节
            LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Teachplan::getParentid,id);  //子章节的父ID = 当前大章节id
            Integer count = teachplanMapper.selectCount(queryWrapper);
            if(count > 0){
                //还有小章节，不能删除
                throw new XuechengOnlineException("课程计划信息还有子信息，无法操作","12409");
            }else{
                //大章节下没有小章节，删除
                teachplanMapper.deleteById(id);
                //同时删除关联的teachplan_media信息
                LambdaQueryWrapper<TeachplanMedia> queryWrapper2 = new LambdaQueryWrapper<>();
                queryWrapper2.eq(TeachplanMedia::getTeachplanId,id);
                teachplanMediaMapper.delete(queryWrapper2);
            }
        }else{
            //大章节!=0 是小章节，直接删除
            teachplanMapper.deleteById(id);
            //同时删除关联的teachplan_media信息
            LambdaQueryWrapper<TeachplanMedia> queryWrapper2 = new LambdaQueryWrapper<>();
            queryWrapper2.eq(TeachplanMedia::getTeachplanId,id);
            teachplanMediaMapper.delete(queryWrapper2);

        }
    }

    /**
     * 课程计划排序
     *
     * @param moveType 移动类型
     * @param id
     */
    @Transactional
    @Override
    public void orderByTeachplan(String moveType, Long id) {
        Teachplan teachplan = teachplanMapper.selectById(id);
        //获取当前层级和当前orderby， 章节移动和小节移动的处理方式不同
        Integer grade = teachplan.getGrade();
        Integer orderby = teachplan.getOrderby();

        //章节移动是比较同一课程id下的orderby
        Long courseId = teachplan.getCourseId();
        //小节移动是比较同一章节id下的ordeby
        Long parentid = teachplan.getParentid();

        if("moveup".equals(moveType)){
            if(grade == 1){
                //章节上移，找到上一个章节的orderby，然后与其交换ordeby
                LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
                        queryWrapper.eq(Teachplan::getGrade,1)
                        .eq(Teachplan::getCourseId, courseId) // 新增：同一课程
                        .lt(Teachplan::getOrderby, orderby)  //比当前排序值小
                        .orderByDesc(Teachplan::getOrderby)  //降序--取最大的
                        .last("LIMIT 1");
                Teachplan tmp = teachplanMapper.selectOne(queryWrapper);
                exchangeOrderby(teachplan,tmp);
            }else if(grade == 2){
                //小节上移
                LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(Teachplan::getParentid,parentid)
                        .eq(Teachplan::getGrade, 2)
                        .lt(Teachplan::getOrderby,orderby)
                        .orderByDesc(Teachplan::getOrderby)
                        .last("LIMIT 1");
                Teachplan tmp = teachplanMapper.selectOne(queryWrapper);
                exchangeOrderby(teachplan,tmp);

            }

        }else if("movedown".equals(moveType)){
            if(grade == 1){
                //章节下移，找到下一个章节的orderby，然后与其交换ordeby
                LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(Teachplan::getGrade,1)
                        .eq(Teachplan::getCourseId, courseId) // 新增：同一课程
                        .gt(Teachplan::getOrderby, orderby)  //比当前排序值小
                        .orderByAsc(Teachplan::getOrderby)  //降序--取最大的
                        .last("LIMIT 1");
                Teachplan tmp = teachplanMapper.selectOne(queryWrapper);
                exchangeOrderby(teachplan,tmp);
            }else if(grade == 2){
                //小节下移
                LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(Teachplan::getParentid,parentid)
                        .eq(Teachplan::getGrade, 2)
                        .gt(Teachplan::getOrderby,orderby)
                        .orderByAsc(Teachplan::getOrderby)
                        .last("LIMIT 1");
                Teachplan tmp = teachplanMapper.selectOne(queryWrapper);
                exchangeOrderby(teachplan,tmp);

            }
        }
    }



    /**
     * 交换两个Teachplan的orderby
     * @param teachplan
     * @param tmp
     */
    private void exchangeOrderby(Teachplan teachplan ,Teachplan tmp) {
        if (tmp == null) {
            throw new XuechengOnlineException("已经到头了，不能再移了");
        } else {
            //交换当前节点和目标节点的排序值
            Integer orderby = teachplan.getOrderby();
            Integer tmpOrderby = tmp.getOrderby();
            teachplan.setOrderby(tmpOrderby);
            teachplanMapper.updateById(teachplan);

            tmp.setOrderby(orderby);
            teachplanMapper.updateById(tmp);
        }
    }

    /**
     * 教学计划绑定媒资
     *
     * @param bindTeachplanMediaDto
     * @return
     */
    @Transactional
    @Override
    public TeachplanMedia associationMedia(BindTeachplanMediaDto bindTeachplanMediaDto) {
        //教学计划id
        Long teachplanId = bindTeachplanMediaDto.getTeachplanId();
        Teachplan teachplan = teachplanMapper.selectById(teachplanId);
        if(teachplan == null){
            XuechengOnlineException.cast("教学计划不存在");
        }

        Integer grade = teachplan.getGrade();
        if(grade != 2){
            XuechengOnlineException.cast("只允许第二级教学计划绑定媒资文件");
        }

        //课程id
        Long courseId = teachplan.getCourseId();

        //先删除原来该教学计划绑定的媒资
        teachplanMediaMapper.delete(new LambdaQueryWrapper<TeachplanMedia>()
                .eq(TeachplanMedia::getTeachplanId,teachplanId));

        //再添加教学计划与媒资的绑定关系
        TeachplanMedia teachplanMedia = new TeachplanMedia();
        teachplanMedia.setMediaId(bindTeachplanMediaDto.getMediaId());
        teachplanMedia.setCourseId(courseId);
        teachplanMedia.setTeachplanId(teachplanId);
        teachplanMedia.setMediaFilename(bindTeachplanMediaDto.getFileName());
        teachplanMedia.setCreateDate(LocalDateTime.now());
        teachplanMediaMapper.insert(teachplanMedia);
        return teachplanMedia;
    }

    /**
     * 删除课程计划的媒资信息
     * @param teachPlanId
     * @param mediaId
     */
    @Override
    public void deleteTeachplanMedia(Long teachPlanId, String mediaId) {
        Teachplan teachplan = teachplanMapper.selectById(teachPlanId);
        if(teachplan == null){
            XuechengOnlineException.cast("课程计划不存在");
        }

        teachplanMediaMapper.deleteTeachplanMediaById(teachPlanId,mediaId);

    }
}
